# -*- coding: utf-8 -*- 
# @File : alphabeta.py
# @Time : 2019/11/7 21:41 
# @Author : yaozi
# @Contact : xt1512326654@sina.cn
from graphics import GraphWin
from tictactoe import TicTacToe
from tttdraw import TTTDraw, TTTInput, time


def alphaBeth(ttt, alpha=0, beta=0, depth=0):
    move = ()
    if ttt.isWin(3, 15, ttt.white):
        # print("-----", ttt.white)
        return -10 + depth, None
    if ttt.isWin(3, 15, ttt.black):
        # print("-----", ttt.white)
        return 10 - depth, None
    # 判断当前操作方
    if ttt.getPlayer() == TicTacToe.BLACK:
        bestValue = -10
        # 获取当前状态下的可执行节点
        for child in ttt.getAllMoves():
            # 对当前节点进行克隆
            ttt_clone = ttt.clone()
            # 对当前节点进行操作
            ttt_clone.play(*child)
            # 获取节点下的权值
            v, _ = alphaBeth(ttt_clone, alpha, beta, depth - 1)
            # 判断返回权值与最优值大小，如果返回值大，则返回值为最优值
            bestValue = max(v, bestValue)
            # 判断最优值和最大下界，如果最优值大于最大下界，则重新修正α值
            alpha = max(bestValue, alpha)
            # 如果α大于等于β则说明优的已经优了，没有再必要进行往下搜索，即停止搜索
            if beta <= alpha:
                break
            # 返回当前状态下的可以移动位置信息
            move = child
        return bestValue, move
    else:
        bestValue = 10
        for child in ttt.getAllMoves():
            ttt_clone = ttt.clone()
            ttt_clone.play(*child)
            v, _ = alphaBeth(ttt_clone, alpha, beta, depth - 1)
            bestValue = min(bestValue, v)
            beta = min(bestValue, beta)
            move = child
            if beta <= alpha:
                break
        return bestValue, move
    return bestValue, move


def main():
    win = GraphWin('alphaBeth - 董尧', 600, 600, autoflush=False)
    ttt = TicTacToe()
    tttdraw = TTTDraw(win)
    tttinput = TTTInput(win)

    # BLACK 主动方
    while win.checkKey() != 'Escape':
        if ttt.getPlayer() == TicTacToe.WHITE:
            t1 = time.perf_counter()
            v, move = alphaBeth(ttt)
            t2 = time.perf_counter()
            print("搜索耗时", t2 - t1)
            if move != ():
                ttt.play(*move)
        tttinput.input(ttt)
        tttdraw.draw(ttt)
        if ttt.isGameOver() is not None:
            time.sleep(1)
            # ttt.reset()
            # win.getMouse()
    win.close()


if __name__ == '__main__':
    main()
